home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / advancec.arc / WINDOW.C < prev   
C/C++ Source or Header  |  1992-01-24  |  22KB  |  922 lines

  1.  
  2. /*
  3.     window.c
  4.  
  5.     window manager functions and variables
  6. */
  7.  
  8. #include "usrif.h"
  9. #undef   NULL
  10. #ifdef TRUE #undef TRUE #endif
  11. #ifdef FALSE #undef FALSE #endif
  12. #include <stdio.h>
  13.  
  14. /* window management variables */
  15. static  window_t  *front, *back;
  16. int     num_windows = 0;
  17.  
  18. /* globals */
  19. extern  seg_t   *desk_seg;
  20. extern  rect_t  screen;
  21.  
  22. /* minimum window size */
  23. #define MIN_WX  100
  24. #define MIN_WY  70
  25.  
  26. /* viewport for window manager */
  27. vport_t *the_port = NULL;
  28.  
  29. /* base rectangle for new_rect() */
  30. rect_t  base_rect;
  31.  
  32. /* new window size */
  33. #define HSIZE   400
  34. #define VSIZE   300
  35.  
  36. /* offsets for new window */
  37. #define HDEL    50
  38. #define VDEL    50
  39.  
  40. #define VBASE   (screen.top-VSIZE-VDEL)
  41. #define HBASE   HDEL
  42.  
  43. /* new window rectangle, offset variables */
  44. int hdir = HDEL, vdir = 0-HDEL;
  45.  
  46. /*
  47.     window manager initialization function
  48.  
  49.     init_window()
  50.         called to reset window list,
  51.         also creates and draws the
  52.         desktop segment
  53. */
  54.  
  55. init_window()
  56. {
  57. vport_t *new_vport();
  58.  
  59.     front = back = NULL;
  60.     num_windows = 0;
  61.  
  62.     /* make primary viewport */
  63.     the_port = new_vport(&screen);
  64.  
  65.     /* map to entire screen */
  66.     the_port->window = &screen;
  67.  
  68.     /* make desktop segment */
  69.     make_desktop();
  70.     draw_seg(desk_seg, the_port);
  71.  
  72.     /* set first window place and size */
  73.     set_rect(&base_rect,
  74.         HBASE, VBASE, HBASE+HSIZE, VBASE+VSIZE);
  75. }
  76.  
  77. /*
  78.     window creation functions
  79.  
  80.     new_window( name, segment, rect )
  81.         instantiates a new window structure,
  82.         creates the window shape segment
  83.         to correspond with name and rect,
  84.         links window into window list,
  85.         draws new window,
  86.         and returns a pointer to new window
  87.  
  88.     new_rect()
  89.         creates new window rectangle,
  90.         offset from last time
  91.         new_rect() was called
  92. */
  93.  
  94. window_t    *new_window( name, segment, rect )
  95. char        *name;
  96. seg_t       *segment;
  97. rect_t      *rect;
  98. {
  99. window_t    *new;
  100. key_t       *mykey, *inst_key();
  101. rect_t      *inst_rect(), *new_rect(), *copy_rect();
  102. text_t      *inst_text();
  103.  
  104. void  view_window();
  105.  
  106.     num_windows++;
  107.     if(num_windows > MAX_WINDOWS)
  108.         return(NULL);
  109.  
  110.     if(new = CALLOC( 1, window_t))
  111.         {
  112.         new->name = name;
  113.  
  114.         /* check for minimum window size */
  115.         if( (rect->right - rect->left) < MIN_WX)
  116.             rect->right = rect->left + MIN_WX;
  117.  
  118.         if( (rect->top - rect->bottom) < MIN_WY)
  119.             rect->top = rect->bottom + MIN_WY;
  120.  
  121.         /* get new window rectangle */
  122.         new->area = rect;
  123.  
  124.         /* make title area rectangle */
  125.         new->title = inst_rect(
  126.             new->area->left + 2,
  127.             new->area->top - 20,
  128.             new->area->right - 2,
  129.             new->area->top - 2);
  130.  
  131.         /* make data area rectangle */
  132.         new->pane = inst_rect(
  133.             new->area->left + 1,
  134.             new->area->bottom + 1,
  135.             new->area->right - 1,
  136.             new->area->top - 22);
  137.  
  138.         /* make segment for window */
  139.         cr_seg( name );
  140.             add_attr(RESET);
  141.  
  142.             /* fill shape background */
  143.             add_attr(FILL);
  144.             add_rect(copy_rect(new->area));
  145.             add_attr(NOFILL);
  146.  
  147.             /* frame shape background */
  148.             add_attr(FRAME);
  149.             add_attr(BLACK);
  150.             add_rect(copy_rect(new->area));
  151.  
  152.             /* fill window title area */
  153.             add_attr(FILL);
  154.             add_attr(BLACK);
  155.             add_rect(copy_rect(new->title));
  156.  
  157.             add_attr(WHITE);
  158.             text(name,
  159.                new->title->left + 8,
  160.                new->title->bottom + 5,
  161.                LEFT , BOTTOM);
  162.  
  163.         new->shape = cl_seg();
  164.  
  165.         new->data = segment;
  166.         new->data_win = copy_rect(segment->bbox);
  167.  
  168.         draw_win( new );
  169.  
  170.         /* link to top of window list */
  171.         /* no windows exist */
  172.         if(front == NULL)
  173.             back = front = new;
  174.  
  175.         /* some windows exist */
  176.         else {
  177.             /* make new window the front window */
  178.             front->prev = new;
  179.             new->next = front;
  180.  
  181.             new->prev = NULL;
  182.             front = new;
  183.             }
  184.         }
  185.     else
  186.         error("can't create new window");
  187.  
  188.     /* set up window customer */
  189.     new->button_fn = &view_window;
  190.     return(new);
  191. }
  192.  
  193.  
  194. rect_t  *new_rect()
  195. {
  196. rect_t  r, *n, *copy_rect();
  197. int p;
  198.  
  199.     /* copy current base window rectangle */
  200.     n = copy_rect(&base_rect);
  201.  
  202.     offset_rect(&base_rect, hdir, vdir);
  203.  
  204.     /* move base rectangle to new position */
  205.     if( base_rect.right > screen.right)
  206.         {
  207.         p = base_rect.bottom;
  208.         set_rect(&base_rect,HBASE,p,HBASE+HSIZE,p+VSIZE);
  209.         }
  210.  
  211.     if( base_rect.bottom < screen.bottom)
  212.         {
  213.         p = base_rect.left;
  214.         set_rect(&base_rect,p,VBASE,p+HSIZE,VBASE+VSIZE);
  215.         }
  216.  
  217.     return(n);
  218. }
  219.  
  220. /*
  221.     window pop function
  222.  
  223.     pop_window(window)
  224.         makes given window the 
  225.         top, or active, window
  226. */
  227.  
  228.  
  229. pop_window( window )
  230. window_t    *window;
  231. {
  232.     /* already on top? */
  233.     if(window == front)
  234.         return;
  235.  
  236.     /* relink to top */
  237.     if(window == back)
  238.         {
  239.         /* window is bottom one */
  240.         window->prev->next = NULL;
  241.         back = window->prev;
  242.         }
  243.     else  /* not front or back */
  244.         {
  245.         window->prev->next = window->next;
  246.         window->next->prev = window->prev;
  247.         }
  248.  
  249.     front->prev = window;
  250.     window->next = front;
  251.  
  252.     window->prev = NULL;
  253.     front = window;
  254.  
  255.    /* draw window */
  256.     draw_win(window);
  257. }
  258.  
  259. /*
  260.     window detection functions
  261.  
  262.     front_window()
  263.         returns window pointer to
  264.         active, or front, window
  265.  
  266.     what_window( where )
  267.         returns pointer to
  268.         top window that the point
  269.         where is in, else NULL
  270.  
  271.     in_window( point, window)
  272.     in_title( point, window)
  273.     in_pane( point, window)
  274.         these return TRUE if point
  275.         is in the region, else FALSE
  276. */
  277.  
  278. window_t    *front_window()
  279. {
  280.     return(front);
  281. }
  282.  
  283. window_t    *what_window( where )
  284. point_t     *where;
  285. {
  286. window_t    *mywin, *inwin;
  287.  
  288.     inwin = NULL;
  289.     mywin = back;
  290.  
  291.     while(mywin != NULL)
  292.         {
  293.         if(in_window( where, mywin ))
  294.             inwin = mywin;
  295.  
  296.         /* next higher window */
  297.         mywin = mywin->prev;
  298.         }
  299.  
  300.     return(inwin);
  301. }
  302.  
  303. in_window( point, window)
  304. point_t     *point;
  305. window_t    *window;
  306. {
  307.     if(pt_in_rect( window->area, point))
  308.         return(TRUE);
  309.  
  310.     return(FALSE);
  311. }
  312.  
  313. in_title( point, window)
  314. point_t     *point;
  315. window_t    *window;
  316. {
  317.     if(pt_in_rect( window->title, point))
  318.         return(TRUE);
  319.  
  320.     return(FALSE);
  321. }
  322.  
  323. in_pane( point, window)
  324. point_t     *point;
  325. window_t    *window;
  326. {
  327.     if(pt_in_rect( window->pane, point))
  328.         return(TRUE);
  329.  
  330.     return(FALSE);
  331. }
  332.  
  333. /*
  334.     window menu control functions
  335.  
  336.     mod_window( event, window )
  337.         queries user for window modification
  338.         for the active window, then performs
  339.         selected modification operation
  340.  
  341.     view_window( event, window )
  342.         queries user for view operation
  343.         for active window, then performs
  344.         selected view operation
  345. */
  346.  
  347. /* operation selection menu item definitions */
  348. #define CANCEL  0
  349. #define MOVE    1
  350. #define SIZE    2
  351. #define CLOSE   3
  352.  
  353. /* window modify operation selection menu items */
  354. char    *mod_ops[4] =
  355.     {
  356.     "Cancel",
  357.     "Move",
  358.     "Size",
  359.     "Close"
  360.     };
  361.  
  362. mod_window( event, window )
  363. event_t     *event;
  364. window_t    *window;
  365. {
  366. int sel;
  367. rect_t  *old_rect, *copy_rect();
  368.  
  369.     /* pops up menu, user selects item */
  370.     sel = pop_up_menu( 4, mod_ops );
  371.  
  372.     /* which item was selected? */ 
  373.     switch(sel)
  374.         {
  375.         case    CANCEL  :
  376.             /* user decided not to modify */
  377.             return;
  378.  
  379.         case    MOVE    :
  380.             /* animate window move */
  381.             {
  382.             point_t first, last, delta;
  383.             key_t   *key;
  384.  
  385.             /* copy window bounds */
  386.             old_rect = copy_rect(window->area);
  387.  
  388.             get_cursor(&first);
  389.             xor_rect(window->area,FRAME);
  390.  
  391.             /* animate window outline */   
  392.             while(event->what != DN_BUTTON_EVENT)
  393.                 {
  394.                 get_cursor(&last);
  395.                 event = get_next_event();
  396.  
  397.                 delta.x = event->where.x - last.x;
  398.                 delta.y = event->where.y - last.y;
  399.  
  400.                 if( delta.x != 0 || delta.y != 0)
  401.                     {
  402.                     /* remove old outline */
  403.                     xor_rect(window->area,FRAME);
  404.  
  405.                     /* set new outline */
  406.                     offset_rect(window->area, delta.x, delta.y);
  407.  
  408.                     /* add new outline */
  409.                     xor_rect(window->area,FRAME);
  410.                     }
  411.                 }
  412.  
  413.             /* found new window size */
  414.             xor_rect(window->area,FRAME);
  415.  
  416.             /* calculate window's change in position */
  417.             delta.x = event->where.x - first.x;
  418.             delta.y = event->where.y - first.y;
  419.  
  420.             /* offset window's regions */
  421.             offset_rect(window->title, delta.x, delta.y);
  422.             offset_rect(window->pane, delta.x, delta.y);
  423.             offset_rect(window->shape->bbox, delta.x, delta.y);
  424.  
  425.             /* offset window's shape segment */
  426.             key = window->shape->data;
  427.  
  428.             while(key != NULL)
  429.                 {
  430.                 switch(key->type)
  431.                     {
  432.                     case RECT :
  433.                         offset_rect(key->key.rect, delta.x, delta.y);
  434.                         break;
  435.                     case TEXT :
  436.                         key->key.text->origin.x += delta.x;
  437.                         key->key.text->origin.y += delta.y;
  438.                         break;
  439.                     }
  440.                 key = key->next;
  441.                 }
  442.  
  443.             /* refresh bit map */
  444.             all_wins( old_rect );
  445.             free(old_rect);
  446.  
  447.             draw_win( window );
  448.             }
  449.             break;
  450.  
  451.         case    SIZE    :
  452.             /* animate window sizing */
  453.             {
  454.             point_t first, last, delta;
  455.             key_t   *key;
  456.  
  457.             /* copy window bounds */
  458.             old_rect = copy_rect(window->area);
  459.  
  460.             first.x = window->area->right;
  461.             first.y = screen.top - window->area->bottom;
  462.             set_cursor(&first);
  463.  
  464.             first.y = window->area->bottom;
  465.  
  466.             xor_rect(window->area,FRAME);
  467.  
  468.             /* animate window outline */   
  469.             while(event->what != DN_BUTTON_EVENT)
  470.                 {
  471.                 get_cursor(&last);
  472.                 event = get_next_event();
  473.  
  474.                 if(event->where.x < (window->area->left + MIN_WX))
  475.                     delta.x = 0;
  476.                 else
  477.                     delta.x = event->where.x - last.x;
  478.  
  479.                 if(event->where.y > (window->area->top - MIN_WY))
  480.                     delta.y = 0;
  481.                 else
  482.                     delta.y = event->where.y - last.y;
  483.  
  484.                 if( delta.x != 0 || delta.y != 0)
  485.                     {
  486.                     /* remove old outline */
  487.                     xor_rect(window->area,FRAME);
  488.  
  489.                     /* set new outline */
  490.                     window->area->right += delta.x;
  491.                     window->area->bottom += delta.y;
  492.  
  493.                     /* add new outline */
  494.                     xor_rect(window->area,FRAME);
  495.                     }
  496.                 }
  497.  
  498.             /* found new window size */
  499.             xor_rect(window->area,FRAME);
  500.  
  501.             /* calculate window's change in position */
  502.             delta.x = window->area->right - first.x;
  503.             delta.y = window->area->bottom - first.y;
  504.  
  505.             /* offset window's regions */
  506.             window->title->right += delta.x;
  507.  
  508.             window->pane->right += delta.x;
  509.             window->pane->bottom += delta.y;
  510.  
  511.             window->shape->bbox->right += delta.x;
  512.             window->shape->bbox->bottom += delta.y;
  513.  
  514.             /* redo window's shape segment
  515.             to reflect new size */
  516.             key = window->shape->data;
  517.  
  518.             while(key != NULL)
  519.                 {
  520.                 if(key->type == RECT)
  521.                     {
  522.                     if(key->key.rect->bottom == window->title->bottom)
  523.                         /* do not change title bottom */
  524.                         key->key.rect->right += delta.x;
  525.  
  526.                     else
  527.                         {
  528.                         key->key.rect->right += delta.x;
  529.                         key->key.rect->bottom += delta.y;
  530.                         }
  531.                     }
  532.                 key = key->next;
  533.                 }
  534.  
  535.             /* refresh bit map */
  536.             all_wins( old_rect );
  537.             free(old_rect);
  538.  
  539.             draw_win( window );
  540.             }
  541.             break;
  542.  
  543.         case    CLOSE   :
  544.             /* remove window */
  545.             purge_window( window);
  546.  
  547.             /* refresh */
  548.             all_wins( window->area );
  549.  
  550.             break;
  551.         }
  552.  
  553.     /* refresh display */
  554. }
  555.  
  556. /* window view operation selection menu items */
  557.  
  558. #define REDUCE  1
  559. #define ENLARGE 2
  560. #define SCROLL  3
  561. #define FIT     4
  562.  
  563. char    *view_ops[5] =
  564.     {
  565.     "Cancel",
  566.     "Reduce",
  567.     "Enlarge",
  568.     "Scroll",
  569.     "Fit"
  570.     };
  571.  
  572. /* scroll operation types */
  573. #define S_UP     0
  574. #define S_LEFT   1
  575. #define S_RIGHT  2
  576. #define S_DOWN   3
  577.  
  578. char    *scroll_ops[4] =
  579.     {
  580.     "Up",
  581.     "Left",
  582.     "Right",
  583.     "Down"
  584.     };
  585.  
  586. void        view_window(event, window)
  587. event_t     *event;
  588. window_t    *window;
  589. {
  590. int sel, zoom, pan, h, w;
  591. rect_t    *copy_rect();
  592.  
  593.     /* pop up view modify menu, user selects item */
  594.     sel = pop_up_menu( 5, view_ops );
  595.  
  596.     switch(sel)
  597.         {
  598.         case  CANCEL    :
  599.             break;
  600.  
  601.         case  REDUCE    :
  602.             h = window->data_win->right - window->data_win->left;
  603.             w = window->data_win->top - window->data_win->bottom;
  604.             zoom = h > w ? h/10 : w/10;
  605.  
  606.             inset_rect(window->data_win, -zoom, -zoom);
  607.             draw_win(window);
  608.             break;
  609.  
  610.         case  ENLARGE   :
  611.             h = window->data_win->right - window->data_win->left;
  612.             w = window->data_win->top - window->data_win->bottom;
  613.             zoom = h < w ? h/10 : w/10;
  614.  
  615.             inset_rect(window->data_win, zoom, zoom);
  616.             draw_win(window);
  617.             break;
  618.  
  619.         case  SCROLL    :
  620.             /* pop up scroll menu, user selects item */
  621.             sel = pop_up_menu( 4, scroll_ops );
  622.  
  623.             h = window->data_win->right - window->data_win->left;
  624.             w = window->data_win->top - window->data_win->bottom;
  625.  
  626.             switch(sel)
  627.                 {
  628.                 case    S_LEFT  :
  629.                     pan = h / 3;
  630.                     offset_rect(window->data_win, pan, 0);
  631.                     break;
  632.  
  633.                 case    S_RIGHT :
  634.                     pan = h / 3;
  635.                     offset_rect(window->data_win, -pan, 0);
  636.                     break;
  637.  
  638.                 case    S_UP    :
  639.                     pan = w / 3;
  640.                     offset_rect(window->data_win, 0, -pan);
  641.                     break;
  642.  
  643.                 case    S_DOWN  :
  644.                     pan = w / 3;
  645.                     offset_rect(window->data_win, 0, pan);
  646.                     break;
  647.                 }
  648.  
  649.             /* do scroll */
  650.             draw_win( window );
  651.             break;
  652.  
  653.         case  FIT       :
  654.             free(window->data_win);
  655.             window->data_win = copy_rect(window->data->bbox);
  656.             draw_win(window);
  657.             break;
  658.         }
  659. }
  660.  
  661. /*
  662.     window drawing functions
  663.  
  664.     draw_win(window)
  665.         draws given window
  666.  
  667.     draw_all()
  668.         draws desktop, then all windows
  669.         from back to front
  670. */
  671.  
  672. draw_win( window )
  673. window_t *window;
  674. {
  675. vport_t winport;
  676. rect_t  tr;
  677.  
  678.     union_rect(&screen,window->area,&tr);
  679.     if( equal_rect(&screen, &tr) == FALSE)
  680.         {
  681.         win_inrect( window, window->area );
  682.         return;
  683.         }
  684.  
  685.     /* hide cursor */
  686.     hide_cursor();
  687.  
  688.     /* draw window's shape segment */
  689.     draw_seg(window->shape, the_port);
  690.  
  691.     if(window->data != NULL)
  692.         {
  693.         /* set up viewport for window's data segment */
  694.         winport.bitmap = window->pane;
  695.         winport.window = window->data_win;
  696.         winport.seg = window->data;
  697.  
  698.         /* draw window's data segment */
  699.         draw_seg(window->data, &winport);
  700.         }
  701.  
  702.     /* show cursor */
  703.     show_cursor();
  704. }
  705.  
  706.  
  707. draw_all()
  708. {
  709. window_t    *mywin;
  710.  
  711.     /* hide cursor */
  712.     hide_cursor();
  713.     draw_seg(desk_seg, the_port);
  714.  
  715.     mywin = back;
  716.     while(mywin != NULL)
  717.         {
  718.         draw_win(mywin);
  719.  
  720.         /* next higher window */
  721.         mywin = mywin->prev;
  722.         }
  723.  
  724.     /* show cursor */
  725.     show_cursor();
  726. }
  727.  
  728. all_wins( inrect )
  729. rect_t  *inrect;
  730. {
  731. window_t    *mywin;
  732. vport_t     winport;
  733.  
  734.     /* hide cursor */
  735.     hide_cursor();
  736.  
  737.     /* add small border */
  738.     inset_rect( inrect, -1, -1);
  739.  
  740.     winport.bitmap = inrect;
  741.     winport.window = inrect;
  742.     draw_seg( desk_seg, &winport);
  743.  
  744.     mywin = back;
  745.     while(mywin != NULL)
  746.         {
  747.         win_inrect( mywin, inrect );
  748.         /* next higher window */
  749.         mywin = mywin->prev;
  750.         }
  751.  
  752.     inset_rect(inrect,1,1);
  753.  
  754.     /* show cursor */
  755.     show_cursor();
  756. }
  757.  
  758. /*
  759.     refresh window in rectangle
  760. */
  761.  
  762. win_inrect( window, rect )
  763. window_t    *window;
  764. rect_t      *rect;
  765. {
  766. vport_t winport;
  767. double  nl, nb, nr, nt, /* normalized display coordinates */
  768.         pw, ph;         /* width and height */
  769. rect_t  sr, pr, wr, tpr, twr;   /* screen, port, and window rect */
  770. rect_t  *copy_rect();
  771.  
  772.     /* hide cursor */
  773.     hide_cursor();
  774.  
  775.     /* clip draw rect to screen */
  776.     sect_rect(&screen, rect, &sr);
  777.  
  778.     /* set up viewport for window's data segment */
  779.     winport.bitmap = copy_rect(&sr);
  780.     offset_rect(winport.bitmap, -1, 0);
  781.     winport.window = &sr;
  782.  
  783.     /* draw window's shape segment */
  784.     draw_seg(window->shape, &winport);
  785.  
  786.     free(winport.bitmap);
  787.  
  788.     if(window->data != NULL)
  789.         {
  790.         if(clip_map( window->pane, window->data_win, &sr, &pr, &wr))
  791.             {
  792.             winport.bitmap = ≺
  793.             winport.window = ≀
  794.  
  795.             /* draw window's data segment */
  796.             draw_seg(window->data, &winport);
  797.             }
  798.         }
  799.  
  800.     /* show cursor */
  801.     show_cursor();
  802. }
  803.  
  804. /*
  805.     clip map takes viewport bounds,
  806.     clipping window, and clipping rectangle
  807.     as arguments; then returns new
  808.     viewport bounds and clipping window
  809. */
  810.  
  811. clip_map( old_port, old_win, clip_rect, new_port, new_win)
  812. rect_t  *old_port,
  813.         *old_win,
  814.         *clip_rect,
  815.         *new_port,
  816.         *new_win;
  817. {
  818. double  nl, nb, nr, nt, /* normalized display coords */
  819.         pw, ph;         /* width and height */
  820.  
  821.     if(sect_rect(clip_rect, old_port, new_port))
  822.         {
  823.         pw = (double) (old_port->right - old_port->left);
  824.         ph = (double) (old_port->top - old_port->bottom);
  825.         /* These must never be equal to 0.0! */
  826.  
  827.         /* convert clipped port to normalized display coordinates */
  828.         nl = ((double) (new_port->left - old_port->left)) / pw;
  829.         nr = ((double) (new_port->right - old_port->left)) / pw;
  830.  
  831.         nb = ((double) (new_port->bottom - old_port->bottom)) / ph;
  832.         nt = ((double) (new_port->top - old_port->bottom)) / ph;
  833.  
  834.         /* find new window */
  835.         pw = (double) (old_win->right - old_win->left);
  836.         ph = (double) (old_win->top - old_win->bottom);
  837.  
  838.         if(nl == 0.0)
  839.             new_win->left = old_win->left;
  840.         else
  841.             new_win->left = old_win->left + (int) ( nl * pw );
  842.  
  843.         if(nb == 0.0)
  844.             new_win->bottom = old_win->bottom;
  845.         else
  846.             new_win->bottom = old_win->bottom + (int) ( nb * ph );
  847.  
  848.         if(nr == 1.0)
  849.             new_win->right = old_win->right;
  850.         else
  851.             new_win->right = old_win->left + (int) ( nr * pw );
  852.  
  853.         if(nt == 1.0)
  854.             new_win->top = old_win->top;
  855.         else
  856.             new_win->top = old_win->bottom + (int) ( nt * ph );
  857.  
  858.         return(TRUE);
  859.         }
  860.     else
  861.         return(FALSE);
  862. }
  863.  
  864. /*
  865.     window removal functions
  866.  
  867.     purge_window(window)
  868.         removes given window from
  869.         linked window list
  870.  
  871.     purge_all()
  872.         resets window list to be empty
  873.  
  874.     Note:
  875.         both functions call draw_all()
  876. */
  877.  
  878. purge_window(window)
  879. window_t    *window;
  880. {
  881. /*
  882.     remove from doubly linked list
  883.     remove window shape segment
  884.     free window structure from memory
  885.  
  886.     Note:
  887.         Only the front or active window
  888.         can be purged.
  889.  
  890.         This does not free the window structure
  891.         or its associated data from memory!
  892. */
  893.  
  894.     if(window == back)
  895.         /* last window in list */
  896.         front = back = NULL;
  897.     else
  898.         {
  899.         front->next->prev = NULL;
  900.         front = front->next;
  901.         }
  902.  
  903.     window->next = window->prev = NULL;
  904.     num_windows--;
  905. }
  906.  
  907. purge_all()
  908. {
  909. /*
  910.     remove all windows
  911.  
  912.     Note:
  913.         This does not free window structures
  914.         or their associated data from memory!
  915. */
  916.     front = back = NULL;
  917.  
  918.     draw_all();
  919.     num_windows = 0;
  920. }
  921.  
  922.